package main

import (
	"flag"
	"fmt"
	"geecache/geecache"
	"log"
	"net/http"
)

var db = map[string]string{
	"Tom":"630",
	"Jack":"589",
	"Sam":"567",
}

func createGroup() *geecache.Group {
	return geecache.NewGroup("scores",2<<10,geecache.GetterFunc(
		func(key string) ([]byte, error) {
			log.Println("[SlowDB] search key",key)
			if v,ok := db[key];ok {
				return []byte(v),nil
			}
			return nil,fmt.Errorf("%s not exists",key)
		}))
}

func startCacheServer(addr string,addrs []string,gee *geecache.Group)  {
	peers := geecache.NewHTTPPool(addr)
	peers.Set(addrs...)
	gee.RegisterPeers(peers)
	log.Println("geecache is running at ",addr)
	log.Fatal(http.ListenAndServe(addr[7:],peers))
}

func startAPIServer(apiAddr string,gee *geecache.Group)  {
	http.Handle("/api",http.HandlerFunc(
		func(writer http.ResponseWriter, request *http.Request) {
			key := request.URL.Query().Get("key")
			view,err := gee.Get(key)
			if err != nil {
				http.Error(writer,err.Error(),http.StatusInternalServerError)
				return
			}
			writer.Header().Set("Content-Type","application/octet-stream")
			writer.Write(view.ByteSlice())
		}))
	log.Println("front server is running at ",apiAddr)
	log.Fatal(http.ListenAndServe(apiAddr[7:],nil))
}

func main()  {
	var port int
	var api bool
	flag.IntVar(&port,"port",8081,"Geecache server port")
	flag.BoolVar(&api,"api",false,"Start a api server?")
	flag.Parse()

	apiAddr := "http://localhost:9999"
	addrMap := map[int]string {
		8081:"http://localhost:8081",
		8082:"http://localhost:8082",
		8083:"http://localhost:8083",
	}

	var addrs []string
	for _,v := range addrMap{
		addrs = append(addrs,v)
	}

	gee := createGroup()
	if api {
		go startAPIServer(apiAddr,gee)
	}

	startCacheServer(addrMap[port],[]string(addrs),gee)
}
